package de.mmis.core.base.abstracttree.serializer.internal;

import java.util.Map;

import de.mmis.core.base.DeserializableAnnotations.DeserializationMethod;
import de.mmis.core.base.Position;
import de.mmis.core.base.abstracttree.InnerNode;
import de.mmis.core.base.abstracttree.Tree;
import de.mmis.core.base.abstracttree.Tree.Type;
import de.mmis.core.base.abstracttree.serializer.AbstractSerializer;
import de.mmis.core.base.abstracttree.serializer.DeserializableException;

/**
 * Serializer class for (de)serializing {@link Position}s from/to Trees
 * 
 * @author Christian Koch
 */
public class PositionSerializer extends AbstractSerializer<Position> {

	@DeserializationMethod
	public static Object deserialize(Tree[] exp, ClassLoader classLoader,
			String id, Map<String, Object> idmap)
			throws DeserializableException {

		return deserializePosition(new InnerNode(exp));
	}

	public static Position deserializePosition(Tree exp)
			throws DeserializableException {
		if (exp.getType() != Type.INNER
				|| ((InnerNode) exp).getNumberOfSubTrees() < 2
				|| ((InnerNode) exp).getNumberOfSubTrees() > 3)
			throw new DeserializableException(exp,
					"Position Tree has to be a struct with 2 or 3 elements");

		if (((InnerNode) exp).getNumberOfSubTrees() == 2)
			return new Position(((InnerNode) exp).getSubTree(0).getAsDouble(),
					((InnerNode) exp).getSubTree(1).getAsDouble());

		return new Position(((InnerNode) exp).getSubTree(0).getAsDouble(),
				((InnerNode) exp).getSubTree(1).getAsDouble(),
				((InnerNode) exp).getSubTree(2).getAsDouble());
	}

	@Override
	public Tree serializeInternal(Position object, boolean explicit,
			Map<Object, String> refmap, ClassLoader classLoader) {
		InnerNode ret = new InnerNode();
		ret.add(Tree.fromObject(new Double(object.x), explicit, refmap,
				classLoader));
		ret.add(Tree.fromObject(new Double(object.y), explicit, refmap,
				classLoader));
		ret.add(Tree.fromObject(new Double(object.z), explicit, refmap,
				classLoader));
		return ret;
	}

	@Override
	public String getTypeIdentifier() {
		return "position";
	}
}
